/*
 * Login.java
 * 
 * Version information
 * 
 * Mar 16, 2006
 * 
 * Copyright (c) AmSoft Systems, 2006
 */
package net.amsoft.iservice.icontact.webapp.struts.action;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.amsoft.iservice.icontact.hibernate.dataObject.LoginData;
import net.amsoft.iservice.icontact.service.IContact;
import net.amsoft.iservice.icontact.util.IContactConstants;
import static net.amsoft.iservice.icontact.util.IContactConstants.*;
import net.amsoft.iservice.icontact.webapp.struts.form.LoginForm;
import net.amsoft.iservice.isso.client.ISSOClient;
import net.amsoft.iservice.util.IServiceUtil;
import net.amsoft.iservice.util.MetaData;
import net.amsoft.iservice.util.ResolverClient;

import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionMessage;
import org.apache.struts.action.ActionMessages;
import org.apache.log4j.Logger;

/**
 * Login action class is used to start a new session for the user/i-name who
 * requests. A user is authenticated using isso service and then granted
 * permission to use the service.
 * 
 * @author rahul
 * 
 */
public class Login extends BaseAction {
	private static final Logger oLogger = Logger.getLogger(Login.class);

	public ActionForward process(ActionMapping oMapping, ActionForm oForm,
			HttpServletRequest oRequest, HttpServletResponse oResponse)
			throws Exception {
		LoginData oLoginData = (LoginData) oRequest.getSession(false)
				.getAttribute(SESSION_LOGIN_OBJ);
		LoginForm oLoginForm = (LoginForm) oForm;
		String sServerName = oRequest.getServerName();
		oLogger.info("process() : entry with data : Synonym="
				+ oLoginForm.getSynonym());

		if (oLoginForm == null || oLoginForm.getSynonym() == null) {
			oLogger.warn("process() : invalid synonym");
			return oMapping.findForward(FWD_CHKLOGIN);
		}
		ActionMessages oMsgs = new ActionErrors();
		MetaData oMetaData = ResolverClient.getFinalMetaData(oLoginForm
				.getSynonym());
		if (oMetaData == null) {
			oLogger.warn("process() : Unresolved=" + oLoginForm.getSynonym());
			oMsgs.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage(
					IContactConstants.ERR_INAME_UNRESOLVED));
			saveErrors(oRequest, oMsgs);
			return oMapping.getInputForward();
		}

		if (!IContact.isSynonymSubscribed(oLoginForm.getSynonym(), oMetaData
				.getGlobalInumber(), sServerName)) {
			oLogger.error("process() : Synonym not subscribed: "
					+ oLoginForm.getSynonym());
			oMsgs.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage(
					ERR_INVALID, "synonym"));
			saveErrors(oRequest, oMsgs);
			return oMapping.getInputForward();
		}
		String sISSOUrl = oMetaData.getISSOUrl();
		String providerID = oMetaData.getProviderID();
		String sSPXri = IContactConstants.getSPXri(sServerName);
		oLogger.debug("process() : ISSO Url: " + sISSOUrl + ", Provider ID: "
				+ providerID + ", SP XRI: " + sSPXri);
		String[] authnContext = IContactConstants.RAC_NAMES_LIST.split(",");
		String sComparison = IContactConstants.RAC_COMPARISON_TYPE;
		String sAuthRequest = ISSOClient.createSAMLAuthRequest(oLoginForm
				.getSynonym(), "", sSPXri, false, sServerName, false,
				authnContext, sComparison);
		oLogger.debug("process() : AuthnContext: " + authnContext
				+ ", Comparison: " + sComparison + ", AuthRequest: "
				+ sAuthRequest);

		String sRelayState = IServiceUtil.generateUniqueID();
		oLoginData.setLoggedInSynonym(oLoginForm.getSynonym());
		oLoginData.setGlobalInumber(oMetaData.getGlobalInumber());
		oLoginData.setRelayState(sRelayState);
		oLoginData
				.setProviderIDHash(IServiceUtil.getOneWayEncValue(providerID));
		oLoginData.setIDPMetaDataEP(oMetaData.getServiceEndPoint());
		oLogger.debug("process() : redirect to " + sISSOUrl);

		// clearing contact completion data
		oRequest.getSession(false).removeAttribute(SESSION_CONTACT_REQ);
		oRequest.getSession(false).removeAttribute(SESSION_REQ_DATA);
		oLogger.info("process() : exit");
		return new ActionForward(ISSOClient.getRedirectRequestURI(sISSOUrl,
				sAuthRequest, sRelayState), true);
	}
}
